
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';
/**
 * 解析时间为字符串
 * @param {(Object|string|number)} time 时间
 * @param {string} cFormat 格式
 * @returns {string | null} 返回时间
 */
export function parseTime (time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null;
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
  let date;
  if (typeof time === 'object') {
    date = time;
  } else {
    if ((typeof time === 'string')) {
      if ((/^[0-9]+$/.test(time))) {
        // support "1548221490638"
        time = parseInt(time);
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/');
      }
    }

    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000;
    }
    date = new Date(time);
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  };
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key];
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value];
    }
    return value.toString().padStart(2, '0');
  });
  return time_str;
}

/**
 * 格式化时间
 * @param {number} time 时间
 * @param {string} option 配置
 * @returns {string} 返回时间
 */
export function formatTime (time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000;
  } else {
    time = +time;
  }
  const d = new Date(time);
  const now = Date.now();

  const diff = (now - d) / 1000;

  if (diff < 30) {
    return '刚刚';
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前';
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前';
  } else if (diff < 3600 * 24 * 2) {
    return '1天前';
  }
  if (option) {
    return parseTime(time, option);
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    );
  }
}

/**
 * 地址信息解析为对象
 * @param {string} url 地址
 * @returns {Object} 数据信息
 */
export function param2Obj (url) {
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ');
  if (!search) {
    return {};
  }
  const obj = {};
  const searchArr = search.split('&');
  searchArr.forEach(v => {
    const index = v.indexOf('=');
    if (index !== -1) {
      const name = v.substring(0, index);
      const val = v.substring(index + 1, v.length);
      obj[name] = val;
    }
  });
  return obj;
}

/**
 * 判断元素是否有class名
 * @param {HTMLElement} elm 元素
 * @param {string} cls class名
 * @returns {boolean} 是否有
 */
export function hasClass (ele, cls) {
  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}

/**
 * 给元素添加class名
 * @param {HTMLElement} elm 元素
 * @param {string} cls class名
 */
export function addClass (ele, cls) {
  if (!hasClass(ele, cls)) ele.className += ' ' + cls;
}

/**
 * 去除元素的class名
 * @param {HTMLElement} elm 元素
 * @param {string} cls class名
 */
export function removeClass (ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
    ele.className = ele.className.replace(reg, ' ');
  }
}

/**
 * @desc 对象赋值,将前面的对象值赋给后面的对象
 * @param {object} sourceObj 基础对象
 * @param {object} targetObj 赋值的对象
 * @return {object} 已经赋值完的对象
 */
export function CopyData (sourceObj, targetObj, fields) {
  if (!fields) {
    for (const i in targetObj) {
      if (typeof targetObj[i] === 'object') {
        targetObj[i] = i in sourceObj ? JSON.parse(JSON.stringify(sourceObj[i])) : targetObj[i];
      } else {
        targetObj[i] = i in sourceObj ? sourceObj[i] : targetObj[i];
      }
    }
  } else if (fields instanceof Array) {
    fields.forEach(field => {
      /** 数据存在才赋值，用于解决页面初始进入验证问题 */
      targetObj[field] = field in sourceObj ? sourceObj[field] : targetObj[field];
    });
  } else {
    for (const field in targetObj) {
      targetObj[field] = field in sourceObj ? sourceObj[field] : targetObj[field];
    }
  }
}
/**
 * @desc 时间格式化
 * @version version=1.0.0 2020-09-02
 * @author yd_yuliping
 * @param { string } format 时间格式 yyyy-MM-dd / yyyy-MM-dd HH:mm:ss / yyyy / yyyy-MM 默认(yyyy-MM-dd HH:mm:ss)
 * @param { string } date 日期
 * @return { string } 格式化后的值
 */
export function FormatDate (date, format) {
  const _date = new Date(date);
  const _y = _date.getFullYear();
  const _M = _date.getMonth() + 1 > 9 ? _date.getMonth() + 1 : '0' + (_date.getMonth() + 1);
  const _d = _date.getDate() > 9 ? _date.getDate() : '0' + _date.getDate();
  const _h = _date.getHours() > 9 ? _date.getHours() : '0' + _date.getHours();
  const _m = _date.getMinutes() > 9 ? _date.getMinutes() : '0' + _date.getMinutes();
  const _s = _date.getSeconds() > 9 ? _date.getSeconds() : '0' + _date.getSeconds();
  var _returnDate = date;
  switch (format) {
    case 'yyyy-MM-dd HH:mm:ss':
      _returnDate = format.replace('yyyy', _y).replace('MM', _M).replace('dd', _d).replace('HH', _h).replace('mm', _m).replace('ss', _s);
      break;
    case 'HH:mm:ss':
      _returnDate = format.replace('HH', _h).replace('mm', _m).replace('ss', _s);
      break;
    case 'HH:mm':
      _returnDate = format.replace('HH', _h).replace('mm', _m);
      break;
    case 'yyyy-MM-dd':
      _returnDate = format.replace('yyyy', _y).replace('MM', _M).replace('dd', _d);
      break;
    case 'yyyy-MM':
      _returnDate = format.replace('yyyy', _y).replace('MM', _M);
      break;
    case 'yyyy':
      _returnDate = format.replace('yyyy', _y);
      break;
    case 'yyyy-MM-dd HH:mm':
      _returnDate = format.replace('yyyy', _y).replace('MM', _M).replace('dd', _d).replace('HH', _h).replace('mm', _m);
      break;
    default:
      _returnDate = format.replace('yyyy', _y).replace('MM', _M).replace('dd', _d);
      break;
  }
  return _returnDate;
}
/**
 * 获取url的query携带的参数数据
 * @param {string} variable 参数键
 */
export function getQueryData (variable) {
  var query = window.location.search.substring(1);
  var vars = query.split('&');
  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split('=');
    if (pair[0] === variable) {
      return pair[1];
    }
  }
  return ('');
}

/**
 * @desc 深拷贝
 * @author yd_yuliping
 * @version version=1.0.0 2020-10-15
 * @param { object } data 目标数据
 * @return { object } 拷贝的对象
*/
export function deepCopy (data) {
  if (typeof data !== 'object') return data;
  const _copyData = Array.isArray(data) ? [] : {};
  for (const i in data) {
    const item = data[i];
    const itemType = Object.prototype.toString.call(item).slice(8, -1);
    switch (itemType) {
      case 'Object':
      case 'Array':
        _copyData[i] = deepCopy(item);
        break;
      default:
        _copyData[i] = item;
        break;
    }
  }
  return _copyData;
}
/**
 * 聚合数据得数组数据
 * @param {array} data 数据
 * @param {stirng} code 聚合节点
 */
export function removeSameData (data, code) {
  var _returnData = {};
  for (var i = 0; i < data.length; i++) {
    var _item = data[i];
    var _name = '';
    if (code) {
      _name = _item[code];
    }
    if (!_returnData[_name]) {
      _returnData[_name] = [];
    }
    _returnData[_name].push(_item);
  }
  var _returnDatas2 = [];
  // eslint-disable-next-line no-redeclare
  for (var i in _returnData) {
    var _datas = {};
    _datas[code] = i;
    _datas.data = _returnData[i];
    _returnDatas2.push(_datas);
  }
  return _returnDatas2;
}

/**
 * @desc 解析身份证号码
 * @author yd_yuliping
 * @version version=1.0.0 2021-01-11
 * @param { string } idNumber
 * @return { object } { gender: '', birth: '' }
*/
export function parseIdNumber (idNumber) {
  const idNumberRegExp = /^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}([0-9]|x|X)$/;
  let gender = '';
  let birth = '';
  // 验证是否符合规则
  if (idNumber !== '' && idNumberRegExp.test(idNumber)) {
    // 根据身份证号码倒数第二位获取性别
    const genderIndex = idNumber.substring(idNumber.length - 1, idNumber.length - 2);
    gender = parseInt(genderIndex) % 2 === 0 ? 'W' : 'M';
    // 根据身份证号码获取出生日期
    birth = idNumber.substring(6, 10) + '-' + idNumber.substring(10, 12) + '-' + idNumber.substring(12, 14);
  }
  return {
    gender: gender,
    birth: birth
  };
}

/**
 * 纯前端导出PDF文件
 * @param {stirng} id DOM节点
 * @param {stirng} pdfName 文件名称
 */
export function getPdf (id, pdfName) {
  var title = pdfName;
  var htmlDom = document.querySelector(id);
  html2Canvas(htmlDom, {
    allowTaint: true,
    scale: 2
  }).then(function (canvas) {
    const contentWidth = canvas.width;
    const contentHeight = canvas.height;
    const pageHeight = contentWidth / 592.28 * 841.89;
    let leftHeight = contentHeight;
    let position = 0;
    const imgWidth = 555.28;
    const imgHeight = 555.28 / contentWidth * contentHeight;
    const pageData = canvas.toDataURL('image/jpeg', 1.0);
    const PDF = new JsPDF('', 'pt', 'a4');
    if (leftHeight < pageHeight) {
      PDF.addImage(pageData, 'JPEG', 20, 20, imgWidth, imgHeight);
    } else {
      while (leftHeight > 0) {
        leftHeight -= pageHeight;
        PDF.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight);
        position -= 841.89;
        if (leftHeight > 0) {
          PDF.addPage();
        }
      }
    }
    PDF.save(title + '.pdf');
  });
}

/**
 * 返回二进制流文件的接口的报错提示
 * @param data error.response.data
 */
export function errorText (data) {
  return new Promise(function (resolve, reject) {
    const reader = new FileReader();
    reader.readAsText(data);
    reader.onload = function () {
      resolve(this.result);
    };
  });
}

/**
 * 处理接口返回的二进制流文件并下载
 * @param data 接口返回的数据res.data
 * @param fileName 文件名+后缀
 */
export function handleReturn (data, fileName) {
  var blob = new Blob([data]);
  if ('msSaveOrOpenBlob' in navigator) {
    window.navigator.msSaveOrOpenBlob(blob, fileName);
    return;
  }
  const downloadElement = document.createElement('a');
  const href = window.URL.createObjectURL(data);

  const key = fileName ? fileName.lastIndexOf('.') : null;
  const str = fileName.substr(key);
  if (str === '.pdf') {
    window.open(href);
  } else {
    downloadElement.style.display = 'none';
    downloadElement.href = href;
    downloadElement.download = fileName;
    document.body.appendChild(downloadElement);
    downloadElement.click();
    document.body.removeChild(downloadElement);
    window.URL.revokeObjectURL(href);
  }
}

/**
 * iframe嵌入页面发送重新登录消息
 */
export function postLoginMsg () {
  try {
    window.parent.postMessage('relogin', '*');
  } catch (error) {
    console.error(error);
  }
}
/**
 * 创建监听
 * @param {string} aType 消息类型
 * @param {function} aFun 回调函数
 */
export function bindIframeMsg (aType, aFun) {
  try {
    window.addEventListener(aType, function (e) {
      if (aFun) {
        aFun(e);
      }
    });
  } catch (error) {
    console.error(error);
  }
}
/**
 * 将货币元转换为分，返回数值
 * @param {number|string} moneyStr 钱数(元)
 * @returns 钱数（分）整数型,后端接收整型，故返回整型
 */
export function moneyYuanToFen (moneyStr) {
  const _moneyStr = String(moneyStr);
  const yuan = Number(_moneyStr.split('.')[0]) || 0;
  const fen = Number(_moneyStr.split('.')[1]) || 0;
  return yuan * 100 + fen;
}

/**
 * 将货币分转换为元，返回字符串
 * @param {number} num 钱数(分)
 * @param {boolean} ignoreFloat 当角分是0时，是否忽略角分，仅显示元
 * @returns 钱数(元) 保留到分 如 '20.00'
 */
export function moneyFenToYuan (num, ignoreFloat) {
  if (typeof num === 'number' && !Number.isNaN(num)) {
    // num 是数字类型 且不是 NaN
    let strNum = String(num); // 金额文本类型
    if (num >= 0) {
      strNum = strNum.padStart(3, '0'); // 用0填充保证最小三位数
      if (ignoreFloat) {
        const _floatNum = strNum.slice(-2);
        if (Number(_floatNum)) {
          return strNum.slice(0, -2) + '.' + _floatNum; // 金额拼接
        } else {
          return strNum.slice(0, -2);
        }
      } else {
        return strNum.slice(0, -2) + '.' + strNum.slice(-2); // 金额拼接
      }
    } else {
      const _mark = strNum.slice(0, 1); // 负号
      const _noMark = strNum.slice(1); // 无负号数值
      strNum = _noMark.padStart(3, '0'); // 用0填充保证最小三位数
      if (ignoreFloat) {
        const _floatNum = strNum.slice(-2);
        if (Number(_floatNum)) {
          return _mark + strNum.slice(0, -2) + '.' + _floatNum; // 金额拼接
        } else {
          return _mark + strNum.slice(0, -2);
        }
      } else {
        return _mark + strNum.slice(0, -2) + '.' + strNum.slice(-2); // 金额拼接
      }
    }
  } else {
    return '';
  }
}
